%{

/*
 *      parser.y
 *      
 *      Copyright 2010 Adam Clark
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include <stdio.h>

#define YYDEBUG 1
#ifndef NULL
#define NULL (void *)0
#endif

#include "parsetree.h"

%}

%union {
	char *string;
	long longval;
	double floatval;
	void *nullval;
	void *StructPtr;
	int TokVal;
	unsigned long Modifiers;
}

%{
void yyprint (FILE *, int, YYSTYPE);
%}

%token <longval> TRUE
%token <longval> FALSE

%token <longval> INTEGERLITERAL
%token <floatval> FLOATINGPOINTLITERAL
%token <longval> BOOLEANLITERAL
%token <nullval> NULLLITERAL
%token <string> STRINGLITERAL
%token <string> CHARACTERLITERAL
%token <string> IDENTIFIER

%token BYTE
%token CHAR
%token DOUBLE
%token FLOAT
%token INT
%token LONG
%token SHORT
%token VOID

%token TOK_AND
%token TOK_AND_ASSIGN
%token TOK_AND_AND
%token TOK_ASSIGN
%token TOK_AT
%token TOK_DOT
%token TOK_COLON
%token TOK_COMMA
%token TOK_ELIPSIS
%token TOK_EQUALS
%token TOK_EXCLAIM
%token TOK_GREATER_EQUAL
%token TOK_GREATER_THAN
%token TOK_LEFT_BRACE
%token TOK_LEFT_PAREN
%token TOK_LEFT_SQUARE
%token TOK_LESS_THAN
%token TOK_LESS_EQUAL
%token TOK_MINUS
%token TOK_MINUS_ASSIGN
%token TOK_MINUS_MINUS
%token TOK_XOR
%token TOK_XOR_ASSIGN
%token TOK_NOT_EQUALS
%token TOK_OR
%token TOK_OR_ASSIGN
%token TOK_OR_OR
%token TOK_PERCENT
%token TOK_PERCENT_ASSIGN
%token TOK_PLUS
%token TOK_PLUS_ASSIGN
%token TOK_PLUS_PLUS
%token TOK_QUESTION
%token TOK_RIGHT_BRACE
%token TOK_RIGHT_PAREN
%token TOK_RIGHT_SQUARE
%token TOK_SEMI_COLON
%token TOK_SHIFT_LEFT
%token TOK_SHIFT_LEFT_ASSIGN
%token TOK_SHIFT_RIGHT
%token TOK_SHIFT_RIGHT_ASSIGN
%token TOK_SHIFT_RIGHT_RIGHT
%token TOK_SHIFT_RIGHT_RIGHT_ASSIGN
%token TOK_SLASH
%token TOK_SLASH_ASSIGN
%token TOK_STAR
%token TOK_STAR_ASSIGN
%token TOK_TILDE
%token TOK_UNARY_PLUS		/* used in the parse tree only */
%token TOK_UNARY_MINUS		/* used in the parse tree only */
%token TOK_CAST				/* used in the parse tree only */
%token TOK_LOCAL_DECL		/* used in the parse tree only */

%token ABSTRACT
%token ASSERT
%token BOOLEAN
%token BREAK
%token CASE
%token CATCH
%token CLASS
%token CONTINUE
%token CONST
%token DEFAULT
%token DO
%token ELSE
%token ENUM
%token EXTENDS
%token FINALLY
%token FOR
%token GOTO
%token IF
%token IMPLEMENTS
%token IMPORT
%token INSTANCEOF
%token INTERFACE
%token FINAL
%token NATIVE
%token NEW
%token PACKAGE
%token PRIVATE
%token PROTECTED
%token PUBLIC
%token RETURN
%token STATIC
%token SUPER
%token STRICTFP
%token SWITCH
%token SYNCHRONIZED
%token THIS
%token THROW
%token THROWS
%token TRANSIENT
%token TRY
%token VOLATILE
%token WHILE

%type <StructPtr>	AbstractMethodDeclaration	/* Method */
%type <StructPtr>	AdditiveExpression			/* Expression */
%type <StructPtr>	AndExpression				/* Expression */
%type <StructPtr>	ArgumentList				/* ArgumentList */
%type <StructPtr>	ArrayAccess					/* Expression */
%type <StructPtr>	ArrayCreationExpression		/* Expression */
%type <StructPtr>	ArrayInitializer			/* Expression */
%type <StructPtr>	ArrayType					/* Expression */
%type <StructPtr>	Assignment					/* Expression */
%type <StructPtr>	AssignmentExpression		/* Expression */
%type <TokVal> 		AssignmentOperator			/* yylval.int */
%type <StructPtr>	BooleanLiteral				/* Literal */
%type <StructPtr>	Block						/* Block */
%type <StructPtr>	BlockStatement				/* Statement */
%type <StructPtr>	BlockStatements				/* Statement */
%type <StructPtr>	BreakStatement				/* BreakStmt */
%type <StructPtr>	CastExpression				/* Expression */
%type <StructPtr>	CatchClause					/* CatchClause */
%type <StructPtr>	Catches						/* CatchClause */
%type <StructPtr>	CharacterLiteral			/* Literal */
%type <StructPtr>	ClassBody					/* ClassMember */
%type <StructPtr>	ClassBodyDeclaration		/* ClassMember */
%type <StructPtr>	ClassBodyDeclarations		/* ClassMember */
%type <StructPtr>	ClassDeclaration			/* TypeDecl */
%type <StructPtr>	ClassInstanceCreationExpression 
												/* Expression */
%type <StructPtr>	ClassMemberDeclaration		/* ClassMember */
%type <StructPtr>	ClassOrInterfaceType		/* Expression */
%type <StructPtr>	ClassType					/* Expression */
%type <StructPtr>	ClassTypeList				/* Expression */
%type <StructPtr>	CompilationUnit				/* CompUnit */
%type <StructPtr>	ConditionalAndExpression	/* Expression */
%type <StructPtr>	ConditionalExpression		/* Expression */
%type <StructPtr>	ConditionalOrExpression		/* Expression */
%type <StructPtr>	ConstantDeclaration			/* Expression */
%type <StructPtr>	ConstantExpression			/* Expression */
%type <StructPtr>	ConstructorBody				/* Block */
%type <StructPtr>	ConstructorDeclaration		/* Method */
%type <StructPtr>	ConstructorDeclarator		/* MethodDecl */
%type <StructPtr>	ContinueStatement			/* ContinueStmt */
%type <StructPtr>	DimExpr						/* ArraySquaresList */
%type <StructPtr>	DimExprs					/* ArraySquaresList */
%type <longval>		Dims						/* yylval.long */
%type <StructPtr>	DoStatement					/* DoStmt */
%type <StructPtr>	EmptyStatement				/* Statement */
%type <StructPtr>	EqualityExpression			/* Expression */
%type <StructPtr>	ExclusiveOrExpression		/* Expression */
%type <StructPtr>	ExplicitConstructorInvocation
												/* Expression */
%type <StructPtr>	Expression					/* Expression */
%type <StructPtr>	ExpressionStatement			/* Expression */
%type <StructPtr>	ExtendsInterfaces			/* Expression */
%type <StructPtr>	FieldAccess					/* Expression */
%type <StructPtr> 	FieldDeclaration			/* Expression */
%type <StructPtr>	Finally						/* Finally */
%type <StructPtr>	FloatingPointLiteral		/* Literal */
%type <StructPtr>	FloatingPointType			/* Identifier */
%type <StructPtr>	ForInit						/* Expression */
%type <StructPtr>	FormalParameter				/* FormalParameter */
%type <StructPtr>	FormalParameterList			/* FormalParameter */
%type <StructPtr>	ForStatement				/* ForStmt */
%type <StructPtr>	ForStatementNoShortIf		/* ForStmt */
%type <StructPtr>	ForUpdate					/* Expression */
%type <string>		Identifier					/* yylval.string */
%type <StructPtr>	IfThenStatement				/* IfStmt */
%type <StructPtr>	IfThenElseStatement			/* IfStmt */
%type <StructPtr>	IfThenElseStatementNoShortIf/* IfStmt */
%type <StructPtr>	ImportDeclaration			/* Expression */
%type <StructPtr>	ImportDeclarations			/* Expression */
%type <StructPtr>	InclusiveOrExpression		/* Expression */
%type <StructPtr>	IntegerLiteral				/* Literal */
%type <StructPtr>	IntegralType				/* Identifier */
%type <StructPtr>	InterfaceBody				/* ClassMember */
%type <StructPtr>	InterfaceDeclaration		/* TypeDecl */
%type <StructPtr>	InterfaceMemberDeclaration	/* ClassMember */
%type <StructPtr>	InterfaceMemberDeclarations	/* ClassMember */
%type <StructPtr>	InterfaceTypeList			/* Expression */
%type <StructPtr>	Interfaces					/* Expression */
%type <StructPtr>	InterfaceType				/* Expression */
%type <StructPtr>	LabeledStatement			/* Statement */
%type <StructPtr>	LabeledStatementNoShortIf	/* Statement */
%type <StructPtr>	LeftHandSide				/* Expression */
%type <StructPtr>	Literal						/* Literal */
%type <StructPtr>	LocalVariableDeclaration 	/* Expression */
%type <StructPtr>	LocalVariableDeclarationStatement
												/* Expression */
%type <StructPtr>	MethodBody					/* Block */
%type <StructPtr>	MethodDeclaration			/* Method */
%type <StructPtr>	MethodDeclarator			/* MethodDecl */
%type <StructPtr>	MethodHeader				/* Method */
%type <StructPtr>	MethodInvocation			/* Expression */
%type <Modifiers>	Modifier					/* yylval.long */
%type <Modifiers>	Modifiers					/* yylval.long */
%type <StructPtr>	MultiplicativeExpression	/* Expression */
%type <StructPtr>	Name						/* Expression */
%type <StructPtr>	NullLiteral					/* Literal */
%type <StructPtr>	NumericType					/* Identifier */
%type <StructPtr>	PackageDeclaration
%type <StructPtr>	PostDecrementExpression		/* Expression */
%type <StructPtr>	PostfixExpression			/* Expression */
%type <StructPtr>	PostIncrementExpression		/* Expression */
%type <StructPtr>	PreDecrementExpression		/* Expression */
%type <StructPtr>	PreIncrementExpression		/* Expression */
%type <StructPtr>	Primary						/* Expression */
%type <StructPtr>	PrimaryNoNewArray			/* Expression */
%type <StructPtr>	PrimitiveType				/* Identifier */
%type <StructPtr>	QualifiedName				/* Expression */
%type <StructPtr>	ReferenceType				/* Expression */
%type <StructPtr>	RelationalExpression		/* Expression */
%type <StructPtr>	ReturnStatement				/* ReturnStmt */
%type <StructPtr>	ShiftExpression				/* Expression */
%type <StructPtr>	SimpleName					/* Identifier */
%type <StructPtr>	SingleTypeImportDeclaration /* Expression */
%type <StructPtr>	Statement					/* Statement */
%type <StructPtr>	StatementExpression			/* Expression */
%type <StructPtr>	StatementExpressionList		/* Expression */
%type <StructPtr>	StatementNoShortIf			/* Statement */
%type <StructPtr>	StatementWithoutTrailingSubstatement
												/* Statement */
%type <StructPtr>	StaticInitializer			/* Block */
%type <StructPtr>	StringLiteral				/* Literal */
%type <StructPtr>	Super						/* Expression */
%type <StructPtr>	SwitchBlock					/* SwitchGroup */
%type <StructPtr>	SwitchBlockStatementGroup	/* SwitchGroup */
%type <StructPtr>	SwitchBlockStatementGroups	/* SwitchGroup */
%type <StructPtr>	SwitchLabel					/* Expression */
%type <StructPtr>	SwitchLabels				/* SwitchLabel */
%type <StructPtr>	SwitchStatement				/* SwitchStmt */
%type <StructPtr>	SynchronizedStatement		/* SynchedStmt */
%type <StructPtr>	Throws						/* Expression */
%type <StructPtr>	ThrowStatement				/* ThrowStmt */
%type <StructPtr>	TryStatement				/* TryStmt */
%type <StructPtr>	Type						/* Expression */
%type <StructPtr>	TypeDeclaration				/* TypeDecl */
%type <StructPtr>	TypeDeclarations			/* TypeDecl */
%type <StructPtr>	TypeImportOnDemandDeclaration 
												/* Expression */
%type <StructPtr>	UnaryExpression				/* Expression */
%type <StructPtr>	UnaryExpressionNotPlusMinus	/* Expression */
%type <StructPtr>	VariableDeclaratorId		/* Identifier */
%type <StructPtr>	VariableDeclarator			/* Expression */
%type <StructPtr>	VariableDeclarators			/* Expression */
%type <StructPtr>	VariableInitializer			/* Expression */
%type <StructPtr>	VariableInitializers		/* Expression */
%type <StructPtr>	WhileStatement				/* WhileStmt */
%type <StructPtr>	WhileStatementNoShortIf		/* WhileStmt */

%%

/*********************************************************************/
Goal
	: CompilationUnit
			{
			};
/*********************************************************************/

/* Ch 4: Types Values & Variables */
/* ============================== */

/*********************************************************************/
Type												/* Expression */
	: PrimitiveType
			{ 
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, $1);
			};
	| ReferenceType
			{ 
				$$ = $1; 
			};
/*********************************************************************/
PrimitiveType										/* Identifier */
	: NumericType
			{	
				$$= $1; 
			};
	| BOOLEAN
			{
				$$ = NewIdentifier(id_Type, tp_Bool, NULL);
			};
/*********************************************************************/
NumericType											/* Identifier */
	: IntegralType			
			{ 
				$$ = $1; 
			};
	| FloatingPointType
			{ 
				$$ = $1; 
			};
/*********************************************************************/
IntegralType										/* Identifier */
	: BYTE
			{
				$$ = NewIdentifier(id_Type, tp_Byte, NULL);
			};
	| SHORT
			{
				$$ = NewIdentifier(id_Type, tp_Short, NULL);
			};
	| INT
			{
				$$ = NewIdentifier(id_Type, tp_Int, NULL);
			};
	| LONG
			{
				$$ = NewIdentifier(id_Type, tp_Long, NULL);
			};
	| CHAR
			{
				$$ = NewIdentifier(id_Type, tp_Char, NULL);
			};
/*********************************************************************/
FloatingPointType									/* Identifier */
	: FLOAT
			{
				$$ = NewIdentifier(id_Type, tp_Float, NULL);
			};
	| DOUBLE
			{
				$$ = NewIdentifier(id_Type, tp_Double, NULL);
			};
/*********************************************************************/
ReferenceType										/* Expression */
	: ClassOrInterfaceType
			{ 
				$$ = $1; 
			};
	| ArrayType
			{ 
				$$ = $1; 
			};
/*********************************************************************/
ClassOrInterfaceType								/* Expression */
	: Name					
			{ 
				$$ = Expr_SetIdentTypeLeft($1, id_Class);
				$$ = Expr_SetPrimTypeLeft($1, tp_Named);
			};
/*********************************************************************/
ClassType											/* Expression */
	: ClassOrInterfaceType
			{ 
				$$ = Expr_SetIdentTypeLeft($1, id_Class);
				$$ = Expr_SetPrimTypeLeft($1, tp_Named);
			};
/*********************************************************************/
InterfaceType										/* Expression */
	: ClassOrInterfaceType
			{ 
				$$ = Expr_SetIdentTypeLeft($1, id_Class);
				$$ = Expr_SetPrimTypeLeft($1, tp_Named);
			};
/*********************************************************************/
ArrayType											/* Expression */
	: PrimitiveType TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				Expr_SetIdentTypeLeft($1, id_Array);
				$1 = Ident_AddArrayDefnCurr ($1);
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, $1);
			};
	| Name TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				Identifier *i = ((Expression *)$1)->leftSideIdent;
				Ident_AddArrayDefnCurr (i);
				
				$$ = Expr_SetIdentTypeLeft($1, id_Array);
				$$ = Expr_SetPrimTypeLeft($$, tp_Named);
			};
	| ArrayType TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				Identifier *i = ((Expression *)$1)->leftSideIdent;
				Ident_AddArrayDefnCurr (i);
				
				$$ = $1;
			};
/*********************************************************************/

/* Ch 6: Names */
/* =========== */

/*********************************************************************/
Name												/* Expression */
	: SimpleName
			{ 
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, $1);
			};
	| QualifiedName
			{ 
				$$ = $1; 
			};
/*********************************************************************/
SimpleName											/* Identifier */
	: Identifier		
			{	
				$$ = NewIdentifier(id_Name, ix_None, $1); 
			};
/*********************************************************************/
QualifiedName										/* Expression */
	: Name TOK_DOT Identifier
			{ 
				$$ = Expr_SetOp($1, TOK_DOT);
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, ix_None, $3));
			};
/*********************************************************************/

/* Ch 7: Packages */
/* ============== */

/*********************************************************************/
CompilationUnit											/* CompUnit */
	: PackageDeclaration ImportDeclarations TypeDeclarations
			{
				$$ = MakeCompUnit($1, $2, $3);
			};
	| PackageDeclaration ImportDeclarations 
			{
				$$ = MakeCompUnit($1, $2, NULL);
			};
	| PackageDeclaration TypeDeclarations
			{
				$$ = MakeCompUnit($1, NULL, $2);
			};
	| PackageDeclaration 
			{
				$$ = MakeCompUnit($1, NULL, NULL);
			};
	| ImportDeclarations TypeDeclarations
			{
				$$ = MakeCompUnit(NULL, $1, $2);
			};
	| ImportDeclarations 
			{
				$$ = MakeCompUnit(NULL, $1, NULL);
			};
	| TypeDeclarations
			{
				$$ = MakeCompUnit(NULL, NULL, $1);
			};
	|
			{
				$$ = MakeCompUnit(NULL, NULL, NULL);
			};
/*********************************************************************/
ImportDeclarations									/* Expression */
	: ImportDeclaration
			{
				$$ = $1;
			};
	| ImportDeclarations ImportDeclaration
			{
				$$ = Expr_AddNextExpr($1, $2);
			};
/*********************************************************************/
TypeDeclarations										/* TypeDecl */
	: TypeDeclaration
			{
				$$ = $1;
			};
	| TypeDeclarations TypeDeclaration
			{
				$$ = Type_SetNextTypeDecl($1, $2);
			};
/*********************************************************************/
PackageDeclaration									/* Expression */
	: PACKAGE Name TOK_SEMI_COLON
			{
				$$ = $2;
			};
/*********************************************************************/
ImportDeclaration									/* Expression */
	: SingleTypeImportDeclaration
			{
				$$ = $1;
			};
	| TypeImportOnDemandDeclaration
			{
				$$ = $1;
			};
/*********************************************************************/
SingleTypeImportDeclaration							/* Expression */
	: IMPORT Name TOK_SEMI_COLON
			{
				$$ = $2;
			};
/*********************************************************************/
TypeImportOnDemandDeclaration						/* Expression */
	: IMPORT Name TOK_DOT TOK_STAR TOK_SEMI_COLON
			{
				$$ = MakeExpr (TOK_DOT);
				$$ = Expr_SetLeftExpr($$, $2);
				$$ = Expr_SetRightLiteral($$, MakeStringLiteral("*"));
			};
/*********************************************************************/
TypeDeclaration											/* TypeDecl */
	: ClassDeclaration
			{
				$$ = $1;
			};
	| InterfaceDeclaration
			{
				$$ = $1;
			};
	| TOK_SEMI_COLON
			{
				$$ = MakeEmptyTypeDecl();
			};
/*********************************************************************/

/* Ch 8: Classes */
/* ============= */

/*********************************************************************/
ClassDeclaration										/* TypeDecl */
	: CLASS Identifier ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, 0, 
					NewIdentifier(id_Name, tp_None, $2), NULL, NULL, $3);
			};
	| Modifiers CLASS Identifier ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, $1, 
					NewIdentifier(id_Name, tp_None, $3), NULL, NULL, $4);
			};
	| CLASS Identifier Super ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, 0, 
					NewIdentifier(id_Name, tp_None, $2), $3, NULL, $4);
			};
	| Modifiers CLASS Identifier Super ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, $1, 
					NewIdentifier(id_Name, tp_None, $3), $4, NULL, $5);
			};
	| CLASS Identifier Interfaces ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, 0, 
					NewIdentifier(id_Name, tp_None, $2), NULL, $3, $4);
			};
	| Modifiers CLASS Identifier Interfaces ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, $1, 
					NewIdentifier(id_Name, tp_None, $3), NULL, $4, $5);
			};
	| CLASS Identifier Super Interfaces ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, 0, 
					NewIdentifier(id_Name, tp_None, $2), $3, $4, $5);
			};
	| Modifiers CLASS Identifier Super Interfaces ClassBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetClass($$, $1, 
					NewIdentifier(id_Name, tp_None, $3), $4, $5, $6);
			};
/*********************************************************************/
Super												/* Expression */
   : EXTENDS ClassType
		{
			$$ = $2;
		};
/*********************************************************************/
Interfaces											/* Expression */
	: IMPLEMENTS InterfaceTypeList
		{
			$$ = $2;
		};
/*********************************************************************/
InterfaceTypeList									/* Expression */
	: InterfaceType
		{
			$$ = $1;
		};
	| InterfaceTypeList TOK_COMMA InterfaceType
		{
			$$ = Expr_AddNextExpr($1, $3);
		};
/*********************************************************************/
ClassBody											/* ClassMember */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{
				$$ = NULL;
			};
	| TOK_LEFT_BRACE ClassBodyDeclarations TOK_RIGHT_BRACE
			{
				$$ = $2;
			};
/*********************************************************************/
ClassBodyDeclarations								/* ClassMember */
	: ClassBodyDeclaration
			{
				$$ = $1;
			};
	| ClassBodyDeclarations ClassBodyDeclaration
			{
				$$ = cmbr_SetNextCMbr($1,$2);
			};
/*********************************************************************/
ClassBodyDeclaration								/* ClassMember */
	: ClassMemberDeclaration
			{
				$$ = $1;
			};
	| StaticInitializer
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetInitializer($$, $1);
			};
	| ConstructorDeclaration
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetField($$, $1);
			};
/*********************************************************************/
ClassMemberDeclaration								/* ClassMember */
	: FieldDeclaration
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetField($$, $1);
			};
	| MethodDeclaration
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetMethod($$, $1);
			};
/*********************************************************************/
FieldDeclaration									/* Expression */
	: Type VariableDeclarators TOK_SEMI_COLON
			{ 
				$$ = MakeExpr(TOK_LOCAL_DECL);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $2);
			};
	| Modifiers Type VariableDeclarators TOK_SEMI_COLON
			{ 
				$$ = MakeExpr(TOK_LOCAL_DECL);
				$$ = Expr_SetLeftExpr($$, $2);
				$$ = Expr_SetRightExpr($$, $3);
				$$ = Expr_SetModifiers($$, $1);
			};
/*********************************************************************/
MethodDeclaration										/* Method */
	: MethodHeader MethodBody
		{
			$$ = Meth_SetBody($1, $2);
		};
/*********************************************************************/
MethodHeader											/* Method */
	: Type MethodDeclarator 
			{
				$$ = MakeMethod(md_Method, 0, $1, $2, NULL);
			};
	| VOID MethodDeclarator
			{
				Identifier *i = NewIdentifier(id_Type, tp_Void, NULL);
				Expression *e = MakeExpr(0);
				
				e = Expr_SetLeftIdent(e, i);
				$$ = MakeMethod(md_Method, 0, e, $2, NULL);
			};
	| Modifiers Type MethodDeclarator 
			{
				$$ = MakeMethod(md_Method, $1, $2, $3, NULL);
			};
	| Modifiers VOID MethodDeclarator 
			{
				Identifier *i = NewIdentifier(id_Type, tp_Void, NULL);
				Expression *e = MakeExpr(0);
				
				e = Expr_SetLeftIdent(e, i);
				$$ = MakeMethod(md_Method, $1, e, $3, NULL);
			};
	| Type MethodDeclarator Throws
			{
				$$ = MakeMethod(md_Method, 0, $1, $2, $3);
			};
	| VOID MethodDeclarator Throws
			{
				Identifier *i = NewIdentifier(id_Type, tp_Void, NULL);
				Expression *e = MakeExpr(0);
				
				e = Expr_SetLeftIdent(e, i);
				$$ = MakeMethod(md_Method, 0, e, $2, $3);
			};
	| Modifiers Type MethodDeclarator Throws
			{
				$$ = MakeMethod(md_Method, $1, $2, $3, $4);
			};
	| Modifiers VOID MethodDeclarator Throws
			{
				Identifier *i = NewIdentifier(id_Type, tp_Void, NULL);
				Expression *e = MakeExpr(0);
				
				e = Expr_SetLeftIdent(e, i);
				$$ = MakeMethod(md_Method, 0, e, $3, $4);
			};
/*********************************************************************/
MethodDeclarator									/* MethodDecl */
	: Identifier TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = MakeMethodDecl(NewIdentifier(id_Name, tp_None, $1), NULL);
			};
	| Identifier TOK_LEFT_PAREN FormalParameterList TOK_RIGHT_PAREN
			{
				$$ = MakeMethodDecl(NewIdentifier(id_Name, tp_None, $1), $3);
			};
	| MethodDeclarator TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				$$ = MethD_AddArraySquares($1);
			};
/*********************************************************************/
FormalParameterList								/* FormalParameter */
	: FormalParameter
			{
				$$ = $1;
			};
	| FormalParameterList TOK_COMMA FormalParameter
			{
				$$ = AppendFormalParameter($1, $3);
			};
/*********************************************************************/
FormalParameter									/* FormalParameter  */
	: Type VariableDeclaratorId
			{ 
				$$ = MakeFormalParameter($1, $2);
			};
/*********************************************************************/
Throws												/* Expression */
	: THROWS ClassTypeList
			{
				$$ = $2;
			};
/*********************************************************************/
ClassTypeList										/* Expression */
	: ClassType
			{
				$$ = $1;
			};
	| ClassTypeList TOK_COMMA ClassType
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/
MethodBody													/* Block */
	: Block
			{
				$$ = $1;
			};
	| TOK_SEMI_COLON
			{
				$$ = NULL;
			}
/*********************************************************************/
StaticInitializer											/* Block */
	: STATIC Block
			{
				$$ = $2;
			};
/*********************************************************************/
ConstructorDeclaration									/* Method */
	: ConstructorDeclarator ConstructorBody
			{
				$$ = MakeMethod (md_Constructor, 0, NULL, $1, NULL);
				$$ = Meth_SetBody($$, $2);
			};
	| Modifiers ConstructorDeclarator ConstructorBody
			{
				$$ = MakeMethod (md_Constructor, $1, NULL, $2, NULL);
				$$ = Meth_SetBody($$, $3);
			};
	| ConstructorDeclarator Throws ConstructorBody
			{
				$$ = MakeMethod (md_Constructor, 0, NULL, $1, $2);
				$$ = Meth_SetBody($$, $3);
			};
	| Modifiers ConstructorDeclarator Throws ConstructorBody
			{
				$$ = MakeMethod (md_Constructor, $1, NULL, $2, $3);
				$$ = Meth_SetBody($$, $4);
			};
/*********************************************************************/
ConstructorDeclarator								/* MethodDecl */
	: SimpleName TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = MakeMethodDecl($1, NULL);
			};
	| SimpleName TOK_LEFT_PAREN FormalParameterList TOK_RIGHT_PAREN
			{
				$$ = MakeMethodDecl($1, $3);
			};
/*********************************************************************/
ConstructorBody											/* Block */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{
				$$ = MakeBlock (NULL);
			};
	| TOK_LEFT_BRACE ExplicitConstructorInvocation TOK_RIGHT_BRACE
			{
				Statement *s = MakeStmt();
				$$ = MakeBlock (Stmt_SetExprStmt(s, $2));
			};
	| TOK_LEFT_BRACE BlockStatements TOK_RIGHT_BRACE
			{
				$$ = MakeBlock ($2);
			};
	| TOK_LEFT_BRACE ExplicitConstructorInvocation BlockStatements TOK_RIGHT_BRACE
			{
				Statement *s = MakeStmt();
				s = Stmt_SetExprStmt(s, $2);
				s = Stmt_SetNextStmt(s, $3);
				$$ = MakeBlock (s);
			};
/*********************************************************************/
ExplicitConstructorInvocation						/* Expression */
	: THIS TOK_LEFT_PAREN TOK_RIGHT_PAREN TOK_SEMI_COLON
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_This, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| THIS TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN TOK_SEMI_COLON
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_This, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $3);
			};
	| SUPER TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| SUPER TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $3);
			};
/*********************************************************************/

/* Ch 9: Interfaces */
/* ================ */

/*********************************************************************/
InterfaceDeclaration									/* TypeDecl */
	: INTERFACE Identifier InterfaceBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetInterface ($$, 0, 
						NewIdentifier(id_Name, tp_None, $2), NULL, $3); 
			};
	| Modifiers INTERFACE Identifier InterfaceBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetInterface ($$, $1, 
						NewIdentifier(id_Name, tp_None, $3), NULL, $4); 
			};
	| INTERFACE Identifier ExtendsInterfaces InterfaceBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetInterface ($$, 0, 
						NewIdentifier(id_Name, tp_None, $2), $3, $4); 
			};
	| Modifiers INTERFACE Identifier ExtendsInterfaces InterfaceBody
			{
				$$ = MakeEmptyTypeDecl();
				$$ = Type_SetInterface ($$, $1, 
						NewIdentifier(id_Name, tp_None, $3), $4, $5); 
			};
/*********************************************************************/
ExtendsInterfaces									/* Expression */
	: EXTENDS InterfaceType
			{
				$$ = MakeExpr (EXTENDS);
				$$ = Expr_SetRightExpr($$, $2);
			};
	| ExtendsInterfaces TOK_COMMA InterfaceType
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/
InterfaceBody										/* ClassMember */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{
				$$ = NULL;
			};
	| TOK_LEFT_BRACE InterfaceMemberDeclarations TOK_RIGHT_BRACE
			{
				$$ = $2;
			};
/*********************************************************************/
InterfaceMemberDeclarations							/* ClassMember */
	: InterfaceMemberDeclaration
			{
				$$ = $1;
			};
	| InterfaceMemberDeclarations InterfaceMemberDeclaration
			{
				$$ = cmbr_SetNextCMbr($1, $2);
			};
/*********************************************************************/
InterfaceMemberDeclaration							/* ClassMember */
	: ConstantDeclaration
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetField($$, $1);
			};
	| AbstractMethodDeclaration
			{
				$$ = MakeEmptyClassMember();
				$$ = cmbr_SetMethod($$, $1);
			};
/*********************************************************************/
ConstantDeclaration									/* Expression */
	: FieldDeclaration
			{
				$$ = $1;
			};
/*********************************************************************/
AbstractMethodDeclaration								/* Member */
	: MethodHeader TOK_SEMI_COLON
			{
				$$ = $1;
				$$ = Meth_SetType($$, md_Abstract);
			};
/*********************************************************************/

/* Ch 10: Arrays */
/* ============= */

/*********************************************************************/
ArrayInitializer									/* Expression */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{
				$$ = NULL;
			};
	| TOK_LEFT_BRACE VariableInitializers TOK_RIGHT_BRACE
			{
				$$ = $2;
			};
	| TOK_LEFT_BRACE TOK_COMMA TOK_RIGHT_BRACE
			{
				$$ = NULL;
			};
	| TOK_LEFT_BRACE VariableInitializers TOK_COMMA TOK_RIGHT_BRACE
			{
				$$ = $2;
			};
/*********************************************************************/
VariableInitializers								/* Expression */
	: VariableInitializer
			{
				$$ = $1; 
			};
	| VariableInitializers TOK_COMMA VariableInitializer
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/

/* Ch 14: Blocks & Statements */
/* ========================== */

/*********************************************************************/
Block													/* Block */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{
				$$ = MakeBlock(NULL);
			};
	| TOK_LEFT_BRACE BlockStatements TOK_RIGHT_BRACE
			{
				$$ = MakeBlock($2);
			};
/*********************************************************************/
BlockStatements											/* Statement */
	: BlockStatement
			{ 
				$$ = $1; 
			};
	| BlockStatements BlockStatement
			{ 
				$$ = Stmt_SetNextStmt ($1, $2); 
			};
/*********************************************************************/
BlockStatement											/* Statement */
	: LocalVariableDeclarationStatement
			{
				$$ = MakeStmt();
				$$ = Stmt_SetVarDeclStmt($$, $1);
			};
	| Statement
			{
				$$ = $1;
			};
/*********************************************************************/
LocalVariableDeclarationStatement					/* Expression */
	: LocalVariableDeclaration TOK_SEMI_COLON
			{
				$$ = $1;
			};
/*********************************************************************/
LocalVariableDeclaration							/* Expression */
	: Type VariableDeclarators
			{ 
				$$ = MakeExpr(TOK_LOCAL_DECL);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $2);
			};
/*********************************************************************/
VariableDeclarators									/* Expression */
	: VariableDeclarator
			{
				$$ = $1;
			};
	| VariableDeclarators TOK_COMMA VariableDeclarator
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/
VariableDeclarator									/* Expression */
	: VariableDeclaratorId
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, $1);
			};
	| VariableDeclaratorId TOK_ASSIGN VariableInitializer
			{
				$$ = MakeExpr(TOK_ASSIGN);
				$$ = Expr_SetLeftIdent($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
VariableInitializer									/* Expression */
	: Expression
			{
				$$ = $1;
			};
	| ArrayInitializer
			{
				$$ = $1;
			};
/*********************************************************************/
Statement												/* Statement */
	: StatementWithoutTrailingSubstatement
			{ 
				$$ = $1; 
			};
	| LabeledStatement
			{ 
				$$ = $1; 
			};
	| IfThenStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetIfStmt ($$, $1);
			};
	| IfThenElseStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetIfStmt ($$, $1);
			};
	| WhileStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetWhileStmt ($$, $1);
			};
	| ForStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetForStmt ($$, $1);
			};
/*********************************************************************/
StatementWithoutTrailingSubstatement					/* Statement */
	: Block
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetBlockStmt ($$, $1);
			};
	| EmptyStatement
			{
				$$ = MakeStmt ();
			};
	| ExpressionStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetExprStmt ($$, $1);
			};
	| SwitchStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetSwitchStmt ($$, $1);
			};
	| DoStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetDoStmt ($$, $1);
			};
	| BreakStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetBreakStmt ($$, $1);
			};
	| ContinueStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetContinueStmt ($$, $1);
			};
	| ReturnStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetReturnStmt ($$, $1);
			};
	| SynchronizedStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetSynchedStmt ($$, $1);
			};
	| ThrowStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetThrowStmt ($$, $1);
			};
	| TryStatement
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetTryStmt ($$, $1);
			};
/*********************************************************************/
StatementNoShortIf										/* Statement */
	: StatementWithoutTrailingSubstatement
			{ 
				$$ = $1; 
			};
	| LabeledStatementNoShortIf
			{ 
				$$ = $1; 
			};
	| IfThenElseStatementNoShortIf
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetIfStmt ($$, $1);
			};
	| WhileStatementNoShortIf
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetWhileStmt ($$, $1);
			};
	| ForStatementNoShortIf
			{
				$$ = MakeStmt ();
				$$ = Stmt_SetForStmt ($$, $1);
			};
/*********************************************************************/
IfThenStatement											/* IfStmt */
	: IF TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeIfStmt ($3, $5, NULL); 
			};
/*********************************************************************/
IfThenElseStatement										/* IfStmt */
	: IF TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN StatementNoShortIf ELSE Statement
			{ 
				$$ = MakeIfStmt ($3, $5, $7); 
			};
/*********************************************************************/
IfThenElseStatementNoShortIf							/* IfStmt */
	: IF TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN StatementNoShortIf ELSE StatementNoShortIf
			{ 
				$$ = MakeIfStmt ($3, $5, $7); 
			};
/*********************************************************************/
EmptyStatement										/* Statement */
	: TOK_SEMI_COLON
			{ 
				$$ = NULL; 
			};
/*********************************************************************/
LabeledStatement									/* Statement */
	: Identifier TOK_COLON Statement
			{
				$$ = Stmt_SetLabel ($3, NewIdentifier(id_None, tp_None, $1));
			};
/*********************************************************************/
LabeledStatementNoShortIf							/* Statement */
	: Identifier TOK_COLON StatementNoShortIf
			{
				$$ = Stmt_SetLabel ($3, NewIdentifier(id_None, tp_None, $1));
			};
/*********************************************************************/
ExpressionStatement									/* Expression */
	: StatementExpression TOK_SEMI_COLON
			{ 
				$$ = $1; 
			};
/*********************************************************************/
StatementExpression									/* Expression */
	: Assignment
			{
				$$ = $1;
			};
	| PreIncrementExpression
			{
				$$ = $1;
			};
	| PreDecrementExpression
			{
				$$ = $1;
			};
	| PostIncrementExpression
			{
				$$ = $1;
			};
	| PostDecrementExpression
			{
				$$ = $1;
			};
	| MethodInvocation
			{
				$$ = $1;
			};
	| ClassInstanceCreationExpression
			{
				$$ = $1;
			};
/*********************************************************************/
SwitchStatement:									/* SwitchStmt */
	SWITCH TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN SwitchBlock
			{ 
				$$ = MakeSwitchStmt ($3, $5); 
			};
/*********************************************************************/
SwitchBlock											/* SwitchGroup */
	: TOK_LEFT_BRACE TOK_RIGHT_BRACE
			{ 
				$$ = NULL; 
			};
	| TOK_LEFT_BRACE SwitchBlockStatementGroups TOK_RIGHT_BRACE
			{ 
				$$ = $2; 
			};
	| TOK_LEFT_BRACE SwitchLabels TOK_RIGHT_BRACE
			{ 
				$$ = MakeSwitchGroup ($2, NULL); 
			};
	| TOK_LEFT_BRACE SwitchBlockStatementGroups SwitchLabels TOK_RIGHT_BRACE
			{ 
				$$ = AppendSwitchGroup($2, MakeSwitchGroup ($3, NULL)); 
			};
/*********************************************************************/
SwitchBlockStatementGroups							/* SwitchGroup */
	: SwitchBlockStatementGroup
			{ 
				$$ = $1; 
			};
	| SwitchBlockStatementGroups SwitchBlockStatementGroup
			{ 
				$$ = AppendSwitchGroup ($1, $2); 
			};
/*********************************************************************/
SwitchBlockStatementGroup							/* SwitchGroup */
	: SwitchLabels BlockStatements
			{ 
				$$ = MakeSwitchGroup ($1, $2); 
			};
/*********************************************************************/
SwitchLabels:										/* SwitchLabel */
	SwitchLabel
			{ 
				$$ = AppendSwitchLabel (NULL, $1); 
			};
	| SwitchLabels SwitchLabel
			{ 
				$$ = AppendSwitchLabel ($1, $2); 
			};
/*********************************************************************/
SwitchLabel											/* Expression */
	: CASE ConstantExpression TOK_COLON
			{
				$$ = $2; 
			};
	| DEFAULT TOK_COLON
			{
				$$ = NULL; 
			};
/*********************************************************************/
WhileStatement											/* WhileStmt */
	: WHILE TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeWhileStmt ($3, $5); 
			};
/*********************************************************************/
WhileStatementNoShortIf									/* WhileStmt */
	: WHILE TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeWhileStmt ($3, $5); 
			};
/*********************************************************************/
DoStatement												/* DoStmt */
	: DO Statement WHILE TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN TOK_SEMI_COLON
			{ 
				$$ = MakeDoStmt ($2, $5); 
			};
/*********************************************************************/
ForStatement											/* ForStmt */
	: FOR TOK_LEFT_PAREN TOK_SEMI_COLON TOK_SEMI_COLON TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt(NULL, NULL, NULL, $6); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON TOK_SEMI_COLON TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt($3, NULL, NULL, $7); 
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON Expression TOK_SEMI_COLON TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt(NULL, $4, NULL, $7); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON Expression TOK_SEMI_COLON TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt($3, $5, NULL, $8); 
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt(NULL, NULL, $5, $7);
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt($3, NULL, $6, $8);
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON Expression TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt(NULL, $4, $6, $8); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON Expression TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN Statement
			{ 
				$$ = MakeForStmt($3, $5, $7, $9); 
			};
/*********************************************************************/
ForStatementNoShortIf									/* ForStmt */
	: FOR TOK_LEFT_PAREN TOK_SEMI_COLON TOK_SEMI_COLON TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt(NULL, NULL, NULL, $6); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON TOK_SEMI_COLON TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt($3, NULL, NULL, $7); 
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON Expression TOK_SEMI_COLON TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt(NULL, $4, NULL, $7); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON Expression TOK_SEMI_COLON TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt($3, $5, NULL, $8); 
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt(NULL, NULL, $5, $7); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt($3, NULL, $6, $8); 
			};
	| FOR TOK_LEFT_PAREN TOK_SEMI_COLON Expression TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt(NULL, $4, $6, $8); 
			};
	| FOR TOK_LEFT_PAREN ForInit TOK_SEMI_COLON Expression TOK_SEMI_COLON ForUpdate TOK_RIGHT_PAREN StatementNoShortIf
			{ 
				$$ = MakeForStmt($3, $5, $7, $9); 
			};
/*********************************************************************/
ForInit												/* Expression */
	: StatementExpressionList			
			{ 
				$$ = $1; 
			};
	| LocalVariableDeclaration
			{ 
				$$ = $1; 
			};
/*********************************************************************/
ForUpdate											/* Expression */
	: StatementExpressionList
			{ 
				$$ = $1; 
			};
/*********************************************************************/
StatementExpressionList								/* Expression */
	: StatementExpression
			{ 
				$$ = $1; 
			};
	| StatementExpressionList TOK_COMMA StatementExpression
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/
BreakStatement									/* BreakStatement */
	: BREAK TOK_SEMI_COLON
			{
				$$ = MakeBreakStmt(NULL);
			};
	| BREAK Identifier TOK_SEMI_COLON
			{
				$$ = MakeBreakStmt(NewIdentifier(id_Name, tp_None, $2));
			};
/*********************************************************************/
ContinueStatement								/* ContinueStatement */
	: CONTINUE TOK_SEMI_COLON
			{
				$$ = MakeContinueStmt(NULL);
			};
	| CONTINUE Identifier TOK_SEMI_COLON
			{
				$$ = MakeContinueStmt(NewIdentifier(id_Name, tp_None, $2));
			};
/*********************************************************************/
ReturnStatement										/* ReturnStmt */
	: RETURN TOK_SEMI_COLON
			{
				$$ = MakeReturnStmt(NULL); 
			};
	| RETURN Expression TOK_SEMI_COLON
			{
				$$ = MakeReturnStmt($2); 
			};
/*********************************************************************/
ThrowStatement										/* ThrowStmt */
	: THROW Expression TOK_SEMI_COLON
			{
				$$ = MakeThrowStmt ($2); 
			};
/*********************************************************************/
SynchronizedStatement								/* SynchedStmt */
	: SYNCHRONIZED TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN Block
			{
				$$ = MakeSynchedStmt($3, $5); 
			};
/*********************************************************************/
TryStatement											/* TryStmt */
	: TRY Block Catches
			{ 
				$$ = MakeTryStmt ($2, $3, NULL); 
			};
	| TRY Block Finally
			{ 
				$$ = MakeTryStmt ($2, NULL, $3); 
			};
	| TRY Block Catches Finally
			{ 
				$$ = MakeTryStmt ($2, $3, $4); 
			};
/*********************************************************************/
Catches												/* CatchClause */
	: CatchClause
			{ 
				$$ = $1; 
			};
	| Catches CatchClause
			{ 
				$$ = AppendCatchClause ($1, $2); 
			};
/*********************************************************************/
CatchClause											/* CatchClause */
	: CATCH TOK_LEFT_PAREN FormalParameter TOK_RIGHT_PAREN Block
			{ 
				$$ = MakeCatchClause($3, $5);
			};
/*********************************************************************/
Finally													/* Block */
	: FINALLY Block
			{ 
				$$ = $2; 
			};
/*********************************************************************/
VariableDeclaratorId								/* Identifier */
	: Identifier	
			{
				$$ = NewIdentifier(id_Name, tp_None, $1);
			};
	| VariableDeclaratorId TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				$$ = Ident_AddArrayDefnCurr($1);
			};
/*********************************************************************/

/* Ch 15: Expressions */
/* ================== */

/*********************************************************************/
Primary												/* Expression */
	: PrimaryNoNewArray
			{ 
				$$ = $1; 
			};
	| ArrayCreationExpression
			{ 
				$$ = $1; 
			};
/*********************************************************************/
PrimaryNoNewArray									/* Expression */
	: Literal
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftLiteral($$, $1);
			};
	| THIS
			{
				$$ = MakeExpr(0);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_This, tp_None, NULL));
			};
	| TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN
			{
				$$ = $2;
			}; 
	| ClassInstanceCreationExpression
			{
				$$ = $1;
			};
	| FieldAccess
			{
				$$ = $1;
			};
	| MethodInvocation
			{
				$$ = $1;
			};
	| ArrayAccess
			{ 
				$$ = $1; 
			};
/*********************************************************************/
Literal													/* Literal */
	: IntegerLiteral
			{ 
				$$ = $1; 
			};
	| FloatingPointLiteral
			{ 
				$$ = $1; 
			};
	| BooleanLiteral
			{ 
				$$ = $1; 
			};
	| CharacterLiteral
			{ 
				$$ = $1; 
			};
	| StringLiteral
			{ 
				$$ = $1; 
			};
	| NullLiteral
			{ 
				$$ = $1; 
			};
/*********************************************************************/
ClassInstanceCreationExpression						/* Expression */
	: NEW ClassType TOK_LEFT_PAREN TOK_RIGHT_PAREN 
			{
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightExpr($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewClass);
			};
	| NEW ClassType TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN 
			{ 
				$2 = Expr_SetArgList($2, $4);
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightExpr($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewClass);
			};
/*********************************************************************/
ArgumentList										/* Expression */
	: Expression
			{
				$$ = $1;
			};
	| ArgumentList TOK_COMMA Expression
			{
				$$ = Expr_AddNextExpr($1, $3);
			};
/*********************************************************************/
ArrayCreationExpression								/* Expression */
	: NEW PrimitiveType DimExprs
			{
				$2 = ConvertArraySquaresList($2, $3);
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightIdent($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewArray);
			};
	| NEW PrimitiveType DimExprs Dims
			{
				$2 = ConvertArraySquaresList($2, $3);
				$2 = Ident_AddArrayDefnCount($2, $4);
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightIdent($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewArray);
			};
	| NEW ClassOrInterfaceType DimExprs 
			{
				Identifier *i = ((Expression *)$2)->leftSideIdent;
				i = ConvertArraySquaresList(i, $3);
				
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightExpr($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewArray);
			};
	| NEW ClassOrInterfaceType DimExprs Dims
			{
				Identifier *i = ((Expression *)$2)->leftSideIdent;
				i = ConvertArraySquaresList(i, $3);
				i = Ident_AddArrayDefnCount(i, $4);
				
				$$ = MakeExpr(NEW);
				$$ = Expr_SetRightExpr($$, $2);
				$$ = Expr_SetRightExprType($$, ex_NewArray);
			};
/*********************************************************************/
DimExprs										/* ArraySquaresList */
	: DimExpr
			{ 
				$$ = $1; 
			};
	| DimExprs DimExpr
			{
				$$ = AppendSquares ($1, $2);
			};
/*********************************************************************/
DimExpr											/* ArraySquaresList */
	: TOK_LEFT_SQUARE Expression TOK_RIGHT_SQUARE
			{
				$$ = AppendSquares (NULL, $2);
			};
/*********************************************************************/
Dims											/* yylval.longval */
	: TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{ 
				$$ = 1; 
			};
	| Dims TOK_LEFT_SQUARE TOK_RIGHT_SQUARE
			{
				$$ = $1 + 1;
			}; 
/*********************************************************************/
FieldAccess											/* Expression */
	: Primary TOK_DOT Identifier
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightIdent($$, NewIdentifier (id_Name, tp_None, NULL));
			};
	| SUPER TOK_DOT Identifier
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Super, tp_None, NULL));
			}; 
/*********************************************************************/
MethodInvocation									/* Expression */
	: Name TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| Name TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN
			{
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $3);
			};
	| Primary TOK_DOT Identifier TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| Primary TOK_DOT Identifier TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $5);
			};
	| SUPER TOK_DOT Identifier TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| SUPER TOK_DOT Identifier TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN
			{
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $5);
			};
	| Name TOK_DOT SUPER TOK_DOT Identifier TOK_LEFT_PAREN TOK_RIGHT_PAREN
			{
				Expression *t = MakeExpr(TOK_DOT);
				t = Expr_SetLeftExpr(t, $1);
				t = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftExpr($$, t);
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
			};
	| Name TOK_DOT SUPER TOK_DOT Identifier TOK_LEFT_PAREN ArgumentList TOK_RIGHT_PAREN
			{
				Expression *t = MakeExpr(TOK_DOT);
				t = Expr_SetLeftExpr(t, $1);
				t = Expr_SetLeftIdent($$, NewIdentifier(id_Super, tp_None, NULL));
				
				$$ = MakeExpr(TOK_DOT);
				$$ = Expr_SetLeftExpr($$, t);
				$$ = Expr_SetRightIdent($$, NewIdentifier(id_Name, tp_None, NULL));
				$$ = Expr_SetLeftExprType($$, ex_Method);
				$$ = Expr_SetArgList($$, $7);
			};
/*********************************************************************/
ArrayAccess											/* Expression */
	: Name TOK_LEFT_SQUARE Expression TOK_RIGHT_SQUARE
			{ 
				Identifier *i = ((Expression *)$1)->leftSideIdent;
				$1 = Ident_AddArrayAccessCurr(i, $3);
				
				$$ = MakeExpr (0);
				$$ = Expr_SetLeftExpr($$, $1);
			};
	| PrimaryNoNewArray TOK_LEFT_SQUARE Expression TOK_RIGHT_SQUARE
			{ 
				Identifier *i = ((Expression *)$1)->leftSideIdent;
				$1 = Ident_AddArrayAccessCurr(i, $3);
				
				$$ = MakeExpr (0);
				$$ = Expr_SetLeftExpr($$, $1);
			};
/*********************************************************************/
PostfixExpression									/* Expression */
	: Primary
			{ 
				$$ = $1; 
			};
	| Name
			{	
				$$ = MakeExpr (0);
				$$ = Expr_SetLeftIdent($$, $1);
			};
	| PostIncrementExpression
			{ 
				$$ = $1; 
			};
	| PostDecrementExpression
			{ 
				$$ = $1; 
			};
/*********************************************************************/
PostIncrementExpression								/* Expression */
	: PostfixExpression TOK_PLUS_PLUS
			{	
				$$ = MakeExpr(TOK_PLUS_PLUS); 
				$$ = Expr_SetLeftExpr($$,$1);
			};
/*********************************************************************/
PostDecrementExpression								/* Expression */
	: PostfixExpression TOK_MINUS_MINUS
			{	
				$$ = MakeExpr(TOK_MINUS_MINUS); 
				$$ = Expr_SetLeftExpr($$, $1);
			};
/*********************************************************************/
UnaryExpression										/* Expression */
	: PreIncrementExpression
			{ 
				$$ = $1; 
			};
	| PreDecrementExpression
			{ 
				$$ = $1; 
			};
	| TOK_PLUS UnaryExpression	
			{	
				$$ = MakeExpr(TOK_UNARY_PLUS); 
				$$ = Expr_SetRightExpr($$, $2);
			};
	| TOK_MINUS UnaryExpression
			{	
				$$ = MakeExpr(TOK_UNARY_MINUS); 
				$$ = Expr_SetRightExpr($$, $2);
			};
	| UnaryExpressionNotPlusMinus
			{ 
				$$ = $1; 
			};
/*********************************************************************/
PreIncrementExpression								/* Expression */
	: TOK_PLUS_PLUS UnaryExpression
			{	
				$$ = MakeExpr(TOK_PLUS_PLUS); 
				$$ = Expr_SetRightExpr($$,$2);
			};
/*********************************************************************/
PreDecrementExpression								/* Expression */
	: TOK_MINUS_MINUS UnaryExpression
			{	
				$$ = MakeExpr(TOK_MINUS_MINUS); 
				$$ = Expr_SetRightExpr($$, $2);
			};
/*********************************************************************/
UnaryExpressionNotPlusMinus							/* Expression */
	: PostfixExpression
			{ 
				$$ = $1;
			};
	| TOK_TILDE UnaryExpression
			{	
				$$ = MakeExpr(TOK_TILDE);
				$$ = Expr_SetRightExpr($$, $2);
			};
	| TOK_EXCLAIM UnaryExpression
			{	
				$$ = MakeExpr(TOK_EXCLAIM); 
				$$ = Expr_SetRightExpr($$, $2);
			};
	| CastExpression
			{ 
				$$ = $1; 
			};
/*********************************************************************/
CastExpression										/* Expression */
	: TOK_LEFT_PAREN PrimitiveType TOK_RIGHT_PAREN UnaryExpression
			{
				$$ = MakeExpr(TOK_CAST);
				$$ = Expr_SetLeftIdent($$, $2);
				$$ = Expr_SetRightExpr($$, $4);
			};
	| TOK_LEFT_PAREN PrimitiveType Dims TOK_RIGHT_PAREN UnaryExpression
			{
				$$ = MakeExpr(TOK_CAST);
				$$ = Expr_SetLeftIdent($$, Ident_AddArrayDefnCount($2, $3));
				$$ = Expr_SetRightExpr($$, $5);
			};
	| TOK_LEFT_PAREN Expression TOK_RIGHT_PAREN UnaryExpressionNotPlusMinus
			{
				$$ = MakeExpr(TOK_CAST);
				$$ = Expr_SetLeftIdent($$, $2);
				$$ = Expr_SetRightExpr($$, $4);
			};
	| TOK_LEFT_PAREN Name Dims TOK_RIGHT_PAREN UnaryExpressionNotPlusMinus
			{
				$$ = MakeExpr(TOK_CAST);
				$$ = Expr_SetLeftIdent($$, Ident_AddArrayDefnCount($2, $3));
				$$ = Expr_SetRightExpr($$, $5);
			};
/*********************************************************************/
MultiplicativeExpression							/* Expression */
	: UnaryExpression
			{ 
				$$ = $1; 
			};
	| MultiplicativeExpression TOK_STAR UnaryExpression
			{	
				$$ = MakeExpr(TOK_STAR);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| MultiplicativeExpression TOK_SLASH UnaryExpression
			{	
				$$ = MakeExpr(TOK_SLASH);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| MultiplicativeExpression TOK_PERCENT UnaryExpression
			{	
				$$ = MakeExpr(TOK_PERCENT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
AdditiveExpression									/* Expression */
	: MultiplicativeExpression
			{ 
				$$ = $1; 
			};
	| AdditiveExpression TOK_PLUS MultiplicativeExpression
			{	
				$$ = MakeExpr(TOK_PLUS);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| AdditiveExpression TOK_MINUS MultiplicativeExpression
			{	
				$$ = MakeExpr(TOK_MINUS);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
ShiftExpression										/* Expression */
	: AdditiveExpression
			{ 
				$$ = $1; 
			};
	| ShiftExpression TOK_SHIFT_LEFT AdditiveExpression
			{	
				$$ = MakeExpr(TOK_SHIFT_LEFT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| ShiftExpression TOK_SHIFT_RIGHT AdditiveExpression
			{	
				$$ = MakeExpr(TOK_SHIFT_RIGHT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| ShiftExpression TOK_SHIFT_RIGHT_RIGHT AdditiveExpression
			{	
				$$ = MakeExpr(TOK_SHIFT_RIGHT_RIGHT);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
RelationalExpression								/* Expression */
	: ShiftExpression	
			{ 
				$$ = $1;
			};
	| RelationalExpression TOK_LESS_THAN ShiftExpression
			{	
				$$ = MakeExpr(TOK_LESS_THAN);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| RelationalExpression TOK_GREATER_THAN ShiftExpression
			{	
				$$ = MakeExpr(TOK_GREATER_THAN);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| RelationalExpression TOK_LESS_EQUAL ShiftExpression
			{	
				$$ = MakeExpr(TOK_LESS_EQUAL);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| RelationalExpression TOK_GREATER_EQUAL ShiftExpression
			{	
				$$ = MakeExpr(TOK_GREATER_EQUAL);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
    | RelationalExpression INSTANCEOF ReferenceType
			{	
				$$ = MakeExpr(INSTANCEOF);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightIdent($$, $3);
			};
/*********************************************************************/
EqualityExpression									/* Expression */
	: RelationalExpression
			{ 
				$$ = $1; 
			};
	| EqualityExpression TOK_EQUALS RelationalExpression
			{	
				$$ = MakeExpr(TOK_EQUALS); 	
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
	| EqualityExpression TOK_NOT_EQUALS RelationalExpression
			{	
				$$ = MakeExpr(TOK_NOT_EQUALS); 	
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
AndExpression										/* Expression */
	: EqualityExpression
			{ 
				$$ = $1; 
			};
	| AndExpression TOK_AND EqualityExpression
			{	
				$$ = MakeExpr(TOK_AND);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
ExclusiveOrExpression								/* Expression */
	: AndExpression
			{ 
				$$ = $1; 
			};
	| ExclusiveOrExpression TOK_XOR AndExpression
			{	
				$$ = MakeExpr(TOK_XOR);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
InclusiveOrExpression								/* Expression */
	: ExclusiveOrExpression
			{ 
				$$ = $1;
			};
	| InclusiveOrExpression TOK_OR ExclusiveOrExpression
			{	
				$$ = MakeExpr(TOK_OR); 
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
ConditionalAndExpression							/* Expression */
	: InclusiveOrExpression
			{ 
				$$ = $1; 
			};
	| ConditionalAndExpression TOK_AND_AND InclusiveOrExpression
			{	
				$$ = MakeExpr(TOK_AND_AND);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
ConditionalOrExpression								/* Expression */
	: ConditionalAndExpression
			{ 
				$$ = $1; 
			};
	| ConditionalOrExpression TOK_OR_OR ConditionalAndExpression
			{
				$$ = MakeExpr(TOK_OR_OR);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
ConditionalExpression								/* Expression */
	: ConditionalOrExpression
			{ 
				$$ = $1; 
			};
	| ConditionalOrExpression TOK_QUESTION Expression TOK_COLON ConditionalExpression
			{
				$$ = MakeExpr(TOK_QUESTION);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_AddThenElse($$, $3, $5);
			};
/*********************************************************************/
AssignmentExpression								/* Expression */
	: ConditionalExpression
			{
				$$ = $1; 
			};
	| Assignment
			{
				$$ = $1; 
			};
/*********************************************************************/
Assignment											/* Expression */
	: LeftHandSide AssignmentOperator AssignmentExpression
			{
				$$ = MakeExpr($2);
				$$ = Expr_SetLeftExpr($$, $1);
				$$ = Expr_SetRightExpr($$, $3);
			};
/*********************************************************************/
LeftHandSide										/* Expression */
	: Name
			{
				$$ = $1; 
			};
	| FieldAccess
			{
				$$ = $1; 
			};
	| ArrayAccess
			{
				$$ = $1; 
			};
/*********************************************************************/
AssignmentOperator									/* yylval.int */
	: TOK_ASSIGN
			{ 
				$$ = TOK_ASSIGN; 
			};
	| TOK_STAR_ASSIGN
			{ 
				$$ = TOK_STAR_ASSIGN; 
			};
	| TOK_SLASH_ASSIGN
			{ 
				$$ = TOK_SLASH_ASSIGN; 
			};
	| TOK_PERCENT_ASSIGN
			{ 
				$$ = TOK_PERCENT_ASSIGN; 
			};
	| TOK_PLUS_ASSIGN
			{ 
				$$ = TOK_PLUS_ASSIGN; 
			};
	| TOK_MINUS_ASSIGN
			{ 
				$$ = TOK_MINUS_ASSIGN; 
			};
	| TOK_SHIFT_LEFT_ASSIGN
			{ 
				$$ = TOK_SHIFT_LEFT_ASSIGN; 
			};
	| TOK_SHIFT_RIGHT_ASSIGN
			{ 
				$$ = TOK_SHIFT_RIGHT_ASSIGN; 
			};
	| TOK_SHIFT_RIGHT_RIGHT_ASSIGN
			{ 
				$$ = TOK_SHIFT_RIGHT_RIGHT_ASSIGN; 
			};
	| TOK_AND_ASSIGN
			{ 
				$$ = TOK_AND_ASSIGN; 
			};
	| TOK_XOR_ASSIGN
			{ 
				$$ = TOK_XOR_ASSIGN; 
			};
	| TOK_OR_ASSIGN	
			{ 
				$$ = TOK_OR_ASSIGN; 
			};
/*********************************************************************/
Expression											/* Expression */
	: AssignmentExpression			
			{ 
				$$ = $1; 
			};
/*********************************************************************/
ConstantExpression									/* Expression */
	: Expression
			{ 
				$$ = $1; 
			};
/*********************************************************************/

/* Extras */
/* ====== */

/*********************************************************************/
BooleanLiteral											/* Literal */
	: TRUE					
			{ 
				$$ = MakeBoolLiteral (1); 
			};
	| FALSE					
			{ 
				$$ = MakeBoolLiteral (0); 
			};
/*********************************************************************/
FloatingPointLiteral									/* Literal */
	: FLOATINGPOINTLITERAL
			{ 
				$$ = MakeLongDoubleLiteral ($1); 
			};
/*********************************************************************/
IntegerLiteral											/* Literal */
	: INTEGERLITERAL
			{ 
				$$ = MakeLongLongLiteral ($1); 
			};
/*********************************************************************/
NullLiteral												/* Literal */
	: NULLLITERAL
			{ 
				$$ = MakeNullLiteral (); 
			};
/*********************************************************************/
StringLiteral											/* Literal */
	: STRINGLITERAL
			{ 
				$$ = MakeStringLiteral ($1); 
			};
/*********************************************************************/
CharacterLiteral										/* Literal */
	: CHARACTERLITERAL		
			{ 
				$$ = MakeCharLiteral (*$1); 
			};
/*********************************************************************/
Identifier											/* yylval.string */
	: IDENTIFIER
			{ 
				$$ = $1; 
			};
/*********************************************************************/
Modifiers											/* yylval.long */
	: Modifier
			{ 
				$$ = $1; 
			};
	| Modifiers Modifier
			{
				$$ = Modifier_AddFlag ($1, $2);
			};
/*********************************************************************/
Modifier											/* yylval.long */
	: PUBLIC
			{ 
				$$ = Modifier_AddFlag (0, ML_PUBLIC);
			};
	| PROTECTED
			{ 
				$$ = Modifier_AddFlag (0, ML_PROTECTED); 
			};
	| PRIVATE
			{ 
				$$ = Modifier_AddFlag (0, ML_PRIVATE); 
			};
	| ABSTRACT
			{ 
				$$ = Modifier_AddFlag (0, ML_ABSTRACT); 
			};
	| STATIC
			{ 
				$$ = Modifier_AddFlag (0, ML_STATIC); 
			};
	| FINAL
			{ 
				$$ = Modifier_AddFlag (0, ML_FINAL); 
			};
	| STRICTFP
			{ 
				$$ = Modifier_AddFlag (0, ML_STRICTFP); 
			};
	| NATIVE
			{ 
				$$ = Modifier_AddFlag (0, ML_NATIVE); 
			};
	| SYNCHRONIZED
			{ 
				$$ = Modifier_AddFlag (0, ML_SYNCHRONIZED); 
			};
	| TRANSIENT
			{ 
				$$ = Modifier_AddFlag (0, ML_TRANSIENT); 
			};
	| VOLATILE
			{ 
				$$ = Modifier_AddFlag (0, ML_VOLATILE); 
			};
/*********************************************************************/
	
%%

void main (void)
{
#ifdef DEBUG
	yydebug=1;
#else
	yydebug=0;
#endif

	yyparse();
}
